/*
 * The Selling Partner API for Sellers
 * The [Selling Partner API for Sellers](https://developer-docs.amazon.com/sp-api/docs/sellers-api-v1-reference) (Sellers API) provides essential information about seller accounts, such as:  - The marketplaces a seller can list in - The default language and currency of a marketplace - Whether the seller has suspended listings  Refer to the [Sellers API reference](https://developer-docs.amazon.com/sp-api/docs/sellers-api-v1-reference) for details about this API's operations, data types, and schemas.
 *
 * OpenAPI spec version: v1
 *
 *
 * NOTE: This class is auto generated by the swagger code generator program.
 * https://github.com/swagger-api/swagger-codegen.git
 * Do not edit the class manually.
 */

package software.amazon.spapi.api.sellers.v1;

import com.amazon.SellingPartnerAPIAA.LWAAccessTokenCache;
import com.amazon.SellingPartnerAPIAA.LWAAccessTokenCacheImpl;
import com.amazon.SellingPartnerAPIAA.LWAAuthorizationCredentials;
import com.amazon.SellingPartnerAPIAA.LWAAuthorizationSigner;
import com.amazon.SellingPartnerAPIAA.LWAException;
import com.amazon.SellingPartnerAPIAA.RestrictedDataTokenSigner;
import com.google.gson.reflect.TypeToken;
import io.github.bucket4j.Bucket;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import software.amazon.spapi.ApiCallback;
import software.amazon.spapi.ApiClient;
import software.amazon.spapi.ApiException;
import software.amazon.spapi.ApiResponse;
import software.amazon.spapi.Configuration;
import software.amazon.spapi.Pair;
import software.amazon.spapi.ProgressRequestBody;
import software.amazon.spapi.StringUtil;
import software.amazon.spapi.models.sellers.v1.GetAccountResponse;
import software.amazon.spapi.models.sellers.v1.GetMarketplaceParticipationsResponse;

public class SellersApi {
    private ApiClient apiClient;
    private Boolean disableRateLimiting;

    public SellersApi(ApiClient apiClient, Boolean disableRateLimiting) {
        this.apiClient = apiClient;
        this.disableRateLimiting = disableRateLimiting;
    }

    private final Configuration config = Configuration.get();

    public final Bucket getAccountBucket =
            Bucket.builder().addLimit(config.getLimit("SellersApi-getAccount")).build();

    public final Bucket getMarketplaceParticipationsBucket = Bucket.builder()
            .addLimit(config.getLimit("SellersApi-getMarketplaceParticipations"))
            .build();

    /**
     * Build call for getAccount
     *
     * @param progressRequestListener Progress request listener
     * @return Call to execute
     * @throws ApiException If fail to serialize the request body object
     * @throws LWAException If calls to fetch LWA access token fails
     */
    private okhttp3.Call getAccountCall(final ProgressRequestBody.ProgressRequestListener progressRequestListener)
            throws ApiException, LWAException {
        Object localVarPostBody = null;

        // create path and map variables
        String localVarPath = "/sellers/v1/account";

        List<Pair> localVarQueryParams = new ArrayList<Pair>();
        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();

        Map<String, String> localVarHeaderParams = new HashMap<String, String>();

        Map<String, Object> localVarFormParams = new HashMap<String, Object>();

        final String[] localVarAccepts = {"application/json"};
        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);

        final String[] localVarContentTypes = {};

        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
        localVarHeaderParams.put("Content-Type", localVarContentType);

        return apiClient.buildCall(
                localVarPath,
                "GET",
                localVarQueryParams,
                localVarCollectionQueryParams,
                localVarPostBody,
                localVarHeaderParams,
                localVarFormParams,
                progressRequestListener);
    }

    private okhttp3.Call getAccountValidateBeforeCall(
            final ProgressRequestBody.ProgressRequestListener progressRequestListener)
            throws ApiException, LWAException {

        return getAccountCall(progressRequestListener);
    }

    /**
     * Returns information about a seller account and its marketplaces. **Usage Plan:** | Rate (requests per second) |
     * Burst | | ---- | ---- | | 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response header returns the usage
     * plan rate limits that were applied to the requested operation, when available. The preceding table indicates the
     * default rate and burst values for this operation. Selling partners whose business demands require higher
     * throughput may have higher rate and burst values than those shown here. For more information, refer to [Usage
     * Plans and Rate Limits in the Selling Partner
     * API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @param restrictedDataToken Restricted Data Token (optional)
     * @return GetAccountResponse
     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public GetAccountResponse getAccount(String restrictedDataToken) throws ApiException, LWAException {
        ApiResponse<GetAccountResponse> resp = getAccountWithHttpInfo(restrictedDataToken);
        return resp.getData();
    }

    /**
     * Returns information about a seller account and its marketplaces. **Usage Plan:** | Rate (requests per second) |
     * Burst | | ---- | ---- | | 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response header returns the usage
     * plan rate limits that were applied to the requested operation, when available. The preceding table indicates the
     * default rate and burst values for this operation. Selling partners whose business demands require higher
     * throughput may have higher rate and burst values than those shown here. For more information, refer to [Usage
     * Plans and Rate Limits in the Selling Partner
     * API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @return GetAccountResponse
     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public GetAccountResponse getAccount() throws ApiException, LWAException {
        ApiResponse<GetAccountResponse> resp = getAccountWithHttpInfo(null);
        return resp.getData();
    }

    /**
     * Returns information about a seller account and its marketplaces. **Usage Plan:** | Rate (requests per second) |
     * Burst | | ---- | ---- | | 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response header returns the usage
     * plan rate limits that were applied to the requested operation, when available. The preceding table indicates the
     * default rate and burst values for this operation. Selling partners whose business demands require higher
     * throughput may have higher rate and burst values than those shown here. For more information, refer to [Usage
     * Plans and Rate Limits in the Selling Partner
     * API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @param restrictedDataToken Restricted Data Token (optional)
     * @return ApiResponse&lt;GetAccountResponse&gt;
     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public ApiResponse<GetAccountResponse> getAccountWithHttpInfo(String restrictedDataToken)
            throws ApiException, LWAException {
        okhttp3.Call call = getAccountValidateBeforeCall(null);

        if (restrictedDataToken != null) {
            okhttp3.Request request = call.request();
            request = RestrictedDataTokenSigner.sign(request, restrictedDataToken, "SellersApi-getAccount");
            call = apiClient.getHttpClient().newCall(request);
        }

        if (disableRateLimiting || getAccountBucket.tryConsume(1)) {
            Type localVarReturnType = new TypeToken<GetAccountResponse>() {}.getType();
            return apiClient.execute(call, localVarReturnType);
        } else throw new ApiException.RateLimitExceeded("getAccount operation exceeds rate limit");
    }

    /**
     * Returns information about a seller account and its marketplaces. **Usage Plan:** | Rate (requests per second) |
     * Burst | | ---- | ---- | | 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response header returns the usage
     * plan rate limits that were applied to the requested operation, when available. The preceding table indicates the
     * default rate and burst values for this operation. Selling partners whose business demands require higher
     * throughput may have higher rate and burst values than those shown here. For more information, refer to [Usage
     * Plans and Rate Limits in the Selling Partner
     * API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @return ApiResponse&lt;GetAccountResponse&gt;
     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public ApiResponse<GetAccountResponse> getAccountWithHttpInfo() throws ApiException, LWAException {
        return getAccountWithHttpInfo(null);
    }

    /**
     * (asynchronously) Returns information about a seller account and its marketplaces. **Usage Plan:** | Rate
     * (requests per second) | Burst | | ---- | ---- | | 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response
     * header returns the usage plan rate limits that were applied to the requested operation, when available. The
     * preceding table indicates the default rate and burst values for this operation. Selling partners whose business
     * demands require higher throughput may have higher rate and burst values than those shown here. For more
     * information, refer to [Usage Plans and Rate Limits in the Selling Partner
     * API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @param callback The callback to be executed when the API call finishes
     * @return The request call
     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public okhttp3.Call getAccountAsync(final ApiCallback<GetAccountResponse> callback)
            throws ApiException, LWAException {
        return getAccountAsync(callback, null);
    }
    /**
     * (asynchronously) Returns information about a seller account and its marketplaces. **Usage Plan:** | Rate
     * (requests per second) | Burst | | ---- | ---- | | 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response
     * header returns the usage plan rate limits that were applied to the requested operation, when available. The
     * preceding table indicates the default rate and burst values for this operation. Selling partners whose business
     * demands require higher throughput may have higher rate and burst values than those shown here. For more
     * information, refer to [Usage Plans and Rate Limits in the Selling Partner
     * API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @param callback The callback to be executed when the API call finishes
     * @param restrictedDataToken Restricted Data Token (optional)
     * @return The request call
     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public okhttp3.Call getAccountAsync(final ApiCallback<GetAccountResponse> callback, String restrictedDataToken)
            throws ApiException, LWAException {

        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;

        if (callback != null) {
            progressRequestListener = callback::onUploadProgress;
        }

        okhttp3.Call call = getAccountValidateBeforeCall(progressRequestListener);

        if (restrictedDataToken != null) {
            okhttp3.Request request = call.request();
            request = RestrictedDataTokenSigner.sign(request, restrictedDataToken, "SellersApi-getAccount");
            call = apiClient.getHttpClient().newCall(request);
        }

        if (disableRateLimiting || getAccountBucket.tryConsume(1)) {
            Type localVarReturnType = new TypeToken<GetAccountResponse>() {}.getType();
            apiClient.executeAsync(call, localVarReturnType, callback);
            return call;
        } else throw new ApiException.RateLimitExceeded("getAccount operation exceeds rate limit");
    }
    /**
     * Build call for getMarketplaceParticipations
     *
     * @param progressRequestListener Progress request listener
     * @return Call to execute
     * @throws ApiException If fail to serialize the request body object
     * @throws LWAException If calls to fetch LWA access token fails
     */
    private okhttp3.Call getMarketplaceParticipationsCall(
            final ProgressRequestBody.ProgressRequestListener progressRequestListener)
            throws ApiException, LWAException {
        Object localVarPostBody = null;

        // create path and map variables
        String localVarPath = "/sellers/v1/marketplaceParticipations";

        List<Pair> localVarQueryParams = new ArrayList<Pair>();
        List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();

        Map<String, String> localVarHeaderParams = new HashMap<String, String>();

        Map<String, Object> localVarFormParams = new HashMap<String, Object>();

        final String[] localVarAccepts = {"application/json", "payload"};
        final String localVarAccept = apiClient.selectHeaderAccept(localVarAccepts);
        if (localVarAccept != null) localVarHeaderParams.put("Accept", localVarAccept);

        final String[] localVarContentTypes = {};

        final String localVarContentType = apiClient.selectHeaderContentType(localVarContentTypes);
        localVarHeaderParams.put("Content-Type", localVarContentType);

        return apiClient.buildCall(
                localVarPath,
                "GET",
                localVarQueryParams,
                localVarCollectionQueryParams,
                localVarPostBody,
                localVarHeaderParams,
                localVarFormParams,
                progressRequestListener);
    }

    private okhttp3.Call getMarketplaceParticipationsValidateBeforeCall(
            final ProgressRequestBody.ProgressRequestListener progressRequestListener)
            throws ApiException, LWAException {

        return getMarketplaceParticipationsCall(progressRequestListener);
    }

    /**
     * Returns a list of marketplaces where the seller can list items and information about the seller&#x27;s
     * participation in those marketplaces. **Usage Plan:** | Rate (requests per second) | Burst | | ---- | ---- | |
     * 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response header returns the usage plan rate limits that were
     * applied to the requested operation, when available. The preceding table indicates the default rate and burst
     * values for this operation. Selling partners whose business demands require higher throughput may have higher rate
     * and burst values than those shown here. For more information, refer to [Usage Plans and Rate Limits in the
     * Selling Partner API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @param restrictedDataToken Restricted Data Token (optional)
     * @return GetMarketplaceParticipationsResponse
     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public GetMarketplaceParticipationsResponse getMarketplaceParticipations(String restrictedDataToken)
            throws ApiException, LWAException {
        ApiResponse<GetMarketplaceParticipationsResponse> resp =
                getMarketplaceParticipationsWithHttpInfo(restrictedDataToken);
        return resp.getData();
    }

    /**
     * Returns a list of marketplaces where the seller can list items and information about the seller&#x27;s
     * participation in those marketplaces. **Usage Plan:** | Rate (requests per second) | Burst | | ---- | ---- | |
     * 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response header returns the usage plan rate limits that were
     * applied to the requested operation, when available. The preceding table indicates the default rate and burst
     * values for this operation. Selling partners whose business demands require higher throughput may have higher rate
     * and burst values than those shown here. For more information, refer to [Usage Plans and Rate Limits in the
     * Selling Partner API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @return GetMarketplaceParticipationsResponse
     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public GetMarketplaceParticipationsResponse getMarketplaceParticipations() throws ApiException, LWAException {
        ApiResponse<GetMarketplaceParticipationsResponse> resp = getMarketplaceParticipationsWithHttpInfo(null);
        return resp.getData();
    }

    /**
     * Returns a list of marketplaces where the seller can list items and information about the seller&#x27;s
     * participation in those marketplaces. **Usage Plan:** | Rate (requests per second) | Burst | | ---- | ---- | |
     * 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response header returns the usage plan rate limits that were
     * applied to the requested operation, when available. The preceding table indicates the default rate and burst
     * values for this operation. Selling partners whose business demands require higher throughput may have higher rate
     * and burst values than those shown here. For more information, refer to [Usage Plans and Rate Limits in the
     * Selling Partner API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @param restrictedDataToken Restricted Data Token (optional)
     * @return ApiResponse&lt;GetMarketplaceParticipationsResponse&gt;
     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public ApiResponse<GetMarketplaceParticipationsResponse> getMarketplaceParticipationsWithHttpInfo(
            String restrictedDataToken) throws ApiException, LWAException {
        okhttp3.Call call = getMarketplaceParticipationsValidateBeforeCall(null);

        if (restrictedDataToken != null) {
            okhttp3.Request request = call.request();
            request = RestrictedDataTokenSigner.sign(
                    request, restrictedDataToken, "SellersApi-getMarketplaceParticipations");
            call = apiClient.getHttpClient().newCall(request);
        }

        if (disableRateLimiting || getMarketplaceParticipationsBucket.tryConsume(1)) {
            Type localVarReturnType = new TypeToken<GetMarketplaceParticipationsResponse>() {}.getType();
            return apiClient.execute(call, localVarReturnType);
        } else throw new ApiException.RateLimitExceeded("getMarketplaceParticipations operation exceeds rate limit");
    }

    /**
     * Returns a list of marketplaces where the seller can list items and information about the seller&#x27;s
     * participation in those marketplaces. **Usage Plan:** | Rate (requests per second) | Burst | | ---- | ---- | |
     * 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response header returns the usage plan rate limits that were
     * applied to the requested operation, when available. The preceding table indicates the default rate and burst
     * values for this operation. Selling partners whose business demands require higher throughput may have higher rate
     * and burst values than those shown here. For more information, refer to [Usage Plans and Rate Limits in the
     * Selling Partner API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @return ApiResponse&lt;GetMarketplaceParticipationsResponse&gt;
     * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public ApiResponse<GetMarketplaceParticipationsResponse> getMarketplaceParticipationsWithHttpInfo()
            throws ApiException, LWAException {
        return getMarketplaceParticipationsWithHttpInfo(null);
    }

    /**
     * (asynchronously) Returns a list of marketplaces where the seller can list items and information about the
     * seller&#x27;s participation in those marketplaces. **Usage Plan:** | Rate (requests per second) | Burst | | ----
     * | ---- | | 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response header returns the usage plan rate limits
     * that were applied to the requested operation, when available. The preceding table indicates the default rate and
     * burst values for this operation. Selling partners whose business demands require higher throughput may have
     * higher rate and burst values than those shown here. For more information, refer to [Usage Plans and Rate Limits
     * in the Selling Partner
     * API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @param callback The callback to be executed when the API call finishes
     * @return The request call
     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public okhttp3.Call getMarketplaceParticipationsAsync(
            final ApiCallback<GetMarketplaceParticipationsResponse> callback) throws ApiException, LWAException {
        return getMarketplaceParticipationsAsync(callback, null);
    }
    /**
     * (asynchronously) Returns a list of marketplaces where the seller can list items and information about the
     * seller&#x27;s participation in those marketplaces. **Usage Plan:** | Rate (requests per second) | Burst | | ----
     * | ---- | | 0.016 | 15 | The &#x60;x-amzn-RateLimit-Limit&#x60; response header returns the usage plan rate limits
     * that were applied to the requested operation, when available. The preceding table indicates the default rate and
     * burst values for this operation. Selling partners whose business demands require higher throughput may have
     * higher rate and burst values than those shown here. For more information, refer to [Usage Plans and Rate Limits
     * in the Selling Partner
     * API](https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits-in-the-sp-api).
     *
     * @param callback The callback to be executed when the API call finishes
     * @param restrictedDataToken Restricted Data Token (optional)
     * @return The request call
     * @throws ApiException If fail to process the API call, e.g. serializing the request body object
     * @throws LWAException If calls to fetch LWA access token fails
     */
    public okhttp3.Call getMarketplaceParticipationsAsync(
            final ApiCallback<GetMarketplaceParticipationsResponse> callback, String restrictedDataToken)
            throws ApiException, LWAException {

        ProgressRequestBody.ProgressRequestListener progressRequestListener = null;

        if (callback != null) {
            progressRequestListener = callback::onUploadProgress;
        }

        okhttp3.Call call = getMarketplaceParticipationsValidateBeforeCall(progressRequestListener);

        if (restrictedDataToken != null) {
            okhttp3.Request request = call.request();
            request = RestrictedDataTokenSigner.sign(
                    request, restrictedDataToken, "SellersApi-getMarketplaceParticipations");
            call = apiClient.getHttpClient().newCall(request);
        }

        if (disableRateLimiting || getMarketplaceParticipationsBucket.tryConsume(1)) {
            Type localVarReturnType = new TypeToken<GetMarketplaceParticipationsResponse>() {}.getType();
            apiClient.executeAsync(call, localVarReturnType, callback);
            return call;
        } else throw new ApiException.RateLimitExceeded("getMarketplaceParticipations operation exceeds rate limit");
    }

    public static class Builder {
        private LWAAuthorizationCredentials lwaAuthorizationCredentials;
        private String endpoint;
        private LWAAccessTokenCache lwaAccessTokenCache;
        private Boolean disableAccessTokenCache = false;
        private Boolean disableRateLimiting = false;

        public Builder lwaAuthorizationCredentials(LWAAuthorizationCredentials lwaAuthorizationCredentials) {
            this.lwaAuthorizationCredentials = lwaAuthorizationCredentials;
            return this;
        }

        public Builder endpoint(String endpoint) {
            this.endpoint = endpoint;
            return this;
        }

        public Builder lwaAccessTokenCache(LWAAccessTokenCache lwaAccessTokenCache) {
            this.lwaAccessTokenCache = lwaAccessTokenCache;
            return this;
        }

        public Builder disableAccessTokenCache() {
            this.disableAccessTokenCache = true;
            return this;
        }

        public Builder disableRateLimiting() {
            this.disableRateLimiting = true;
            return this;
        }

        public SellersApi build() {
            if (lwaAuthorizationCredentials == null) {
                throw new RuntimeException("LWAAuthorizationCredentials not set");
            }

            if (StringUtil.isEmpty(endpoint)) {
                throw new RuntimeException("Endpoint not set");
            }

            LWAAuthorizationSigner lwaAuthorizationSigner = null;
            if (disableAccessTokenCache) {
                lwaAuthorizationSigner = new LWAAuthorizationSigner(lwaAuthorizationCredentials);
            } else {
                if (lwaAccessTokenCache == null) {
                    lwaAccessTokenCache = new LWAAccessTokenCacheImpl();
                }
                lwaAuthorizationSigner = new LWAAuthorizationSigner(lwaAuthorizationCredentials, lwaAccessTokenCache);
            }

            return new SellersApi(
                    new ApiClient()
                            .setLWAAuthorizationSigner(lwaAuthorizationSigner)
                            .setBasePath(endpoint),
                    disableRateLimiting);
        }
    }
}
